home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
asm09
/
asm09.c
next >
Wrap
Text File
|
1991-10-18
|
53KB
|
1,297 lines
/***************************************************************************/
/* */
/* 6809&6309アセンブラ ASM09 Version1.0 */
/* 1991年8月23日(水) */
/* By Jun.Dime */
/* */
/* このアセンブラはFM-Townsを対象にかかれたものであり、 */
/* High-C以外及びDOS|Extender以外での動作は確認 */
/* していません。 */
/***************************************************************************/
pragma Ipath("a:/inc/");
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define BEGIN { /****************************************/
#define END } /* */
#define IF if( /* この表記法は純正Cプログラマには */
#define THEN ){ /* 許し難いものでしょうが、Cの表記に */
#define ELSE }else{ /* にいつまでも馴れない者の悪掻きだと */
#define ELSEIF }else{if( /* 思ってやってください。PASCAL */
#define ENDIF } /* 風に最初するつもりだったのですが、 */
#define WHILE while( /* 長年親しんだMW-Basic風にな */
#define DO ){ /* ってしまいました。 */
#define FOR for( /* */
#define TO ; /* */
#define BY ; /* */
#define LOOP for(;;){ /* */
#define ENDWHILE } /* */
#define REPEAT do{ /* */
#define UNTIL(s) }while(s); /* */
#define SWITCH(s) switch(s){ /* */
#define CASE(s) case(s): /* */
#define DEFAULT default: /* */
#define BREAK break; /* */
#define ENDSWITCH } /* */
#define RETURN(s) return(s); /* */
#define FUNCTION int /* */
#define MODULE void /* */
#define OR || /* */
#define AND && /* */
#define NOT ! /* */
#define EQU == /* */
#define NEQ != /* */
#define MODULE void /* */
#define ON 0xFF /* */
#define OFF 0x00 /* */
#define TAB 0x09 /* */
#define LF 0x0A /* */
#define CR 0x0D /* */
#define BLANK 0x20 /* */
#define COMMA 0x2C /* */
#define ZERO 0x00 /****************************************/
typedef struct OP {char op[5],Code ;} OPCODE;
typedef struct SYM {char *SP,*SA ;} SYMBOL;
typedef struct CA {char *Label
,*Instruction
,*Argment;
int ArgmentC;} COMLINE;
typedef struct CI {char *Code
,*Argment;
int Code_Count
,Arg_Count;} CODEINF;
struct Registar { char R[3];
int Numb;
} RNum[16] = {{ "D",0x06},{ "X",0x10},{ "Y",0x20},{ "U",0x40}
,{ "S",0x40},{"PC",0x80},{ "W",0x00},{ "V",0x00}
,{ "A",0x04},{ "B",0x02},{"CC",0x01},{"DP",0x08}
,{ "N",0x00},{ "M",0x00},{ "E",0x00},{ "F",0x00}};
char Post_Register[4][2] = {"X","Y","U","S"};
char Code_Info[2][3] = {{0x70,0x00,0x60},{0x30,0x00,0x20}};
char PArea[65536] ,Symbol_Table[65536]
,EQUL_Table[65536],EQU_Table[65536]
,SETL_Table[65536],SET_Table[65536];
int Pass_flag = 0,Symbol_Count;
SYMBOL Symbol[255],Equ[255],Set[255];
int Byte_Count ;
/******************** 6309 asm Main routin **********************************/
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
MODULE main(argc,argv)
int argc;
char *argv[];
BEGIN
FILE *fp,*temp_fp,*Ofp;
char Label[255],Instruction[10],Argment[255],One_Line[255]/*,*TP*/;
/* SYMBOL Symbol[255],Equ[255],Set[255];*/
COMLINE ComLine;
/* CODEINF CodeInf;*/
int i,bc,ArgmentC,c,Line_Count,EQU_Count,SET_Count;
Byte_Count = bc = c = Line_Count = Symbol_Count = EQU_Count = SET_Count = 0;
ComLine.Label = Label;
ComLine.Instruction = Instruction;
ComLine.Argment = Argment;
IF argc < 2 THEN
exit(0);
ENDIF
i = 0;
WHILE strcmp((char *)argv[i],"-c") NEQ ZERO AND i < argc DO
i++;
ENDWHILE
fp = fopen(argv[i + 1],"r");
i = 0;
WHILE strcmp((char *)argv[i],"-o") NEQ ZERO AND i < argc DO
i++;
ENDWHILE
Ofp = fopen(argv[i + 1],"w");
temp_fp = fopen("temp.$$$","w");
Symbol[Symbol_Count].SP = Symbol_Table;
Equ[EQU_Count].SP = EQUL_Table;
Set[SET_Count].SP = SETL_Table;
Equ[EQU_Count].SA = EQU_Table;
Set[SET_Count].SA = SET_Table;
WHILE fgets(One_Line,255,fp) NEQ ZERO DO
/* printf("%05d ",Line_Count++);*/
IF One_Line[0] EQU '*' THEN
strcpy(Label,One_Line);
Label[strlen(Label) - 1] = ZERO;
/* printf(" %s\n",Label);*/
ELSE
Command_Analysis(One_Line,Label,Instruction,Argment);
fputs(Label,temp_fp);fputs(" ",temp_fp);
fputs(Instruction,temp_fp);fputs(" ",temp_fp);
/* fputs(Argment,temp_fp);fputs(" \n",temp_fp);*/
IF strcmp(Instruction,"SET") EQU ZERO
OR strcmp(Instruction,"EQU") EQU ZERO THEN
IF strcmp(Instruction,"EQU") EQU ZERO THEN
Symbol_Entry(ComLine,Equ,&EQU_Count);
ENDIF
IF strcmp(Instruction,"SET") EQU ZERO THEN
Symbol_Entry(ComLine,Set,&SET_Count);
ENDIF
ELSE
IF Symbol_Entry(ComLine,Symbol,&Symbol_Count) > ZERO THEN
Symbol[Symbol_Count - 1].SA = (char *)bc;
ENDIF
ENDIF
IF Instruction[0] NEQ ZERO THEN
fputs(Argment,temp_fp);fputs(" \n",temp_fp);
ComLine.ArgmentC = ArgmentC = Argment_Count(Argment);
/* fputs(Argment,temp_fp);fputs(" \n",temp_fp);*/
/* Number_Analysis(Argment,ArgmentC,temp_fp);*/
IF ArgmentC EQU 1 THEN
ENDIF
IF (c = One_Byte_Code(Instruction,&PArea[bc])) EQU 0 THEN
IF (c = Two_Byte_Code(Instruction,&PArea[bc])) EQU 0 THEN
IF (c = Search_Branch(Instruction
,Argment,&PArea[bc],bc)) EQU 0 THEN
IF (c = Inherent_Code(Instruction,Argment
,ArgmentC,&PArea[bc])) EQU 0 THEN
IF (c = ExImmediate_Code(Instruction,Argment
,ArgmentC,&PArea[bc])) EQU 0 THEN
IF (c = InInstruction(Instruction,Argment
,ArgmentC,&PArea[bc])) EQU 0 THEN
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
/* Command_Line_Print(ComLine,bc,c);*/
bc = bc + c;
ENDIF
ENDWHILE
fclose(fp);
fclose(temp_fp);
Pass_flag = 1;
Line_Count = bc = 0;
fp = fopen("temp.$$$","r");
WHILE fgets(One_Line,255,fp) NEQ ZERO DO
printf("%05d ",Line_Count++);
IF One_Line[0] EQU '*' THEN
printf(" %s\n",Label);
ELSE
Command_Analysis(One_Line,Label,Instruction,Argment);
IF Instruction[0] NEQ ZERO THEN
ComLine.ArgmentC = ArgmentC = Argment_Count(Argment);
IF (c = One_Byte_Code(Instruction,&PArea[bc])) EQU 0 THEN
IF (c = Two_Byte_Code(Instruction,&PArea[bc])) EQU 0 THEN
IF (c = Search_Branch(Instruction
,Argment,&PArea[bc],bc)) EQU 0 THEN
IF (c = Inherent_Code(Instruction,Argment
,ArgmentC,&PArea[bc])) EQU 0 THEN
IF (c = ExImmediate_Code(Instruction,Argment
,ArgmentC,&PArea[bc])) EQU 0 THEN
IF (c = InInstruction(Instruction,Argment
,ArgmentC,&PArea[bc])) EQU 0 THEN
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
Command_Line_Print(ComLine,bc,c);
bc = bc + c;
ENDIF
ENDWHILE
fclose(fp);
fwrite(PArea,bc,1,Ofp);
fclose(Ofp);
Dump_Code(PArea,bc);
printf("\n************************* Label list ***********************");
Symbol_Print(Symbol,Symbol_Count,0);
/* printf("\n************************* EQU list ***********************");
Symbol_Print(Equ,EQU_Count,1);
printf("\n************************* SET list ***********************");
Symbol_Print(Set,SET_Count,1);*/
END
/******************** 6309 asm Main routin **********************************/
/************************ Command Analysis *********************************/
/* */
/* */
/* */
/* */
/* */
/* テキストファイルから1行を読み込みラベル・命令・パラメータに振り */
/* 分ける。 */
/* */
/****************************************************************************/
FUNCTION Command_Analysis(One_Line,Label,Instruction,Argment)
char *One_Line
,*Label
,*Instruction
,*Argment;
BEGIN
int i,j,Return_Variable;
Return_Variable = Label[0] = Instruction[0] = Argment[0] = i = j = 0;
WHILE One_Line[i] > BLANK AND i < 255 DO
Label[j] = toupper(One_Line[i]);
j = j + 1;
i = i + 1;
ENDWHILE
Label[i] = OFF;
WHILE (One_Line[i] EQU BLANK
OR One_Line[i] EQU TAB ) AND i < 255 DO
i = i + 1;
ENDWHILE
j = 0;
WHILE One_Line[i] > BLANK AND i < 255 DO
Instruction[j] = toupper(One_Line[i]);
j = j + 1;
i = i + 1;
ENDWHILE
Instruction[j] = OFF;
WHILE (One_Line[i] EQU BLANK
OR One_Line[i] EQU TAB ) AND i < 255 DO
i = i + 1;
ENDWHILE
j = 0;
WHILE One_Line[i] > BLANK AND i < 255 DO
Argment[j] = toupper(One_Line[i]);
j = j + 1;
i = i + 1;
ENDWHILE
Argment[j] = OFF;
RETURN(Return_Variable);
END
/************************ Command Analysis *********************************/
/************************** Argment Count *********************************/
/* */
/* ”,”を一つの区切りとし、スペースを終了コードとしてパラメータの数 */
/* をカウントする。この時、”,”はヌルコードに置き換える。 */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Argment_Count(Argment)
char Argment[];
BEGIN
int i,k;
i = k = 0;
IF strlen(Argment) NEQ ZERO THEN
k = 1;
WHILE Argment[i] NEQ ZERO DO
IF Argment[i] EQU COMMA THEN
Argment[i] = OFF;
k++;
ENDIF
i++;
ENDWHILE
ENDIF
RETURN(k);
END
/************************** Argment Count *********************************/
/************************ One Byte Code Analysis ****************************/
/* */
/* 本ルーチンでは1バイト命令インハレントコードのみを処理する。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION One_Byte_Code(Instruction,Code)
char *Instruction
,*Code;
BEGIN
static struct
OP Oop[34] = {{ "ABX",0x3A},{"SYNC",0x13},{ "NOP",0x12},{ "MUL",0x3D}
,{ "SWI",0x3F},{ "DAA",0x19}
,{"ASLA",0x48},{"LSLA",0x48},{"ASLB",0x58},{"LSLB",0x58}
,{"ASRA",0x47},{"ASRB",0x57},{"CLRA",0x4F},{"CLRB",0x5F}
,{"COMA",0x43},{"COMB",0x53},{"DECA",0x4A},{"DECB",0x5A}
,{"ROLA",0x49},{"ROLB",0x59},{"RORA",0x46},{"RORB",0x56}
,{ "RTI",0x3B},{ "RTS",0x39},{ "SEX",0x1D},{"SEXW",0x14}
,{"TSTA",0x4D},{"TSTB",0x5D},{"INCA",0x4C},{"INCB",0x5C}
,{"LSRA",0x44},{"LSRB",0x54},{"NEGA",0x40},{"NEGB",0x50}};
int i = 0;
WHILE strcmp(Instruction,Oop[i].op) NEQ ZERO AND i < 34 DO
i++;
ENDWHILE
IF i < 34 THEN
Code[0] = Oop[i].Code;
i = 1;
ELSE
i = 0;
ENDIF
RETURN(i);
END
/************************ One Byte Code Analysis ****************************/
/************************ Two Byte Code Analysis ****************************/
/* */
/* 本ルーチンでは2バイト命令インハレントコードのみを処理する。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Two_Byte_Code(Instruction,Code)
char *Instruction
,*Code;
BEGIN
static struct
OP T10op[26] = {{ "ASLD",0x48},{ "NEGD",0x40},{ "SWI2",0x3F}
,{ "ASLD",0x48},{ "LSLD",0x48},{ "ASRD",0x47}
,{ "CLRD",0x4F},{ "CLRW",0x5F},{ "COMD",0x43},{ "COMW",0x53}
,{ "DECD",0x4A},{ "DECW",0x5A},{ "ROLD",0x49},{ "ROLW",0x59}
,{ "RORD",0x46},{ "RORW",0x56},{ "TSTD",0x4D},{ "TSTW",0x5D}
,{ "INCD",0x4C},{ "INCW",0x5C},{ "LSRD",0x44},{ "LSRW",0x54}
,{"PSHSW",0x38},{"PSHUW",0x3A},{"PULSW",0x37},{"PULUW",0x3B}
};
static struct
OP T11op[11] = {{ "SWI3",0x3F}
,{ "CLRE",0x4F},{ "CLRF",0x5F},{ "COME",0x43},{ "COMF",0x53}
,{ "DECE",0x4A},{ "DECF",0x5A},{ "TSTE",0x4D},{ "TSTF",0x5D}
,{ "INCE",0x4C},{ "INCF",0x5C}};
int i = 0;
WHILE strcmp(Instruction,T10op[i].op) NEQ ZERO AND i < 26 DO
i++;
ENDWHILE
IF i < 26 THEN
Code[0] = 0x10;
Code[1] = T10op[i].Code;
i = 2;
ELSE
i = 0;
WHILE strcmp(Instruction,T11op[i].op) NEQ ZERO AND i < 11 DO
i++;
ENDWHILE
IF i < 11 THEN
Code[0] = 0x11;
Code[1] = T11op[i].Code;
i = 2;
ENDIF
i = 0;
ENDIF
RETURN(i);
END
/************************ One Byte Code Analysis ****************************/
/************************ Inherent Code Analysis ****************************/
/* */
/* インハレントコードの中でもポストバイトの処理を要するものを処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Inherent_Code(Instruction,Argment,ArgmentC,Code)
char *Instruction
,*Argment;
int ArgmentC;
unsigned char *Code;
BEGIN
static struct
OP IOop[6] = {{ "TFR",0x1F},{ "EXG",0x1E}
,{"PSHS",0x34},{"PSHU",0x36},{"PULS",0x35},{"PULU",0x37}};
static struct
OP I10op[8] = {{"ADCR",0x31},{"ADDR",0x30},{"ANDR",0x34},{"CMPR",0x37}
,{"SBCR",0x33},{"SUBR",0x32},{"EORR",0x36},{ "ORR",0x35}};
int i,j,k,re;
char *TP,TEMP[2][10];
i = j = k = re = 0;
Code[0] = Code[1] = Code[2] = ZERO;
TP = Argment;
WHILE strcmp(Instruction,IOop[i].op) NEQ ZERO AND i < 6 DO
i++;
ENDWHILE
IF i < 6 THEN
Code[0] = IOop[i].Code;
IF i EQU 0 OR i EQU 1 THEN
WHILE strcmp(TP,RNum[Code[1] / 0x10].R) NEQ ZERO DO
Code[1] = Code[1] + 0x10;
ENDWHILE
TP = TP + strlen(TP) + 1;
WHILE strcmp(TP,RNum[Code[1] & 0x0f].R) NEQ ZERO DO
Code[1]++;
ENDWHILE
ELSE
WHILE j++ < ArgmentC DO
k = 0 ;
WHILE strcmp(TP,RNum[k].R) NEQ ZERO DO
k++;
ENDWHILE
TP = TP + strlen(TP) + 1;
Code[1] = Code[1] | RNum[k].Numb;
ENDWHILE
ENDIF
re = 2;
ENDIF
i = 0;
WHILE strcmp(Instruction,I10op[i].op) NEQ ZERO AND i < 8 DO
i++;
ENDWHILE
IF i < 8 THEN
Code[0] = 0x10;
Code[1] = I10op[i].Code;
WHILE strcmp(TP,RNum[Code[2] / 0x10].R) NEQ ZERO DO
Code[2] = Code[2] + 0x10;
ENDWHILE
TP = TP + strlen(TP) + 1;
WHILE strcmp(TP,RNum[Code[2] & 0x0f].R) NEQ ZERO DO
Code[2]++;
ENDWHILE
re = 3;
ENDIF
IF strcmp(Instruction,"TFM") EQU ZERO THEN
strcpy(TEMP[0],TP);
TP = TP + strlen(TP) + 1;
strcpy(TEMP[1],TP);
Code[0] = 0x11;
IF TEMP[0][strlen(TEMP[0]) - 1] EQU '-'
AND TEMP[1][strlen(TEMP[1]) - 1] EQU '-' THEN
Code[1] = 0x39;
TEMP[0][strlen(TEMP[0]) - 1] = ZERO;
TEMP[1][strlen(TEMP[1]) - 1] = ZERO;
ELSE
IF TEMP[0][strlen(TEMP[0]) - 1] EQU '+' THEN
TEMP[0][strlen(TEMP[0]) - 1] = ZERO;
IF TEMP[1][strlen(TEMP[1]) - 1] EQU '+' THEN
TEMP[1][strlen(TEMP[1]) - 1] = ZERO;
Code[1] = 0x38;
ELSE
Code[1] = 0x3A;
ENDIF
ELSE
IF TEMP[1][strlen(TEMP[1]) - 1] EQU '+' THEN
TEMP[1][strlen(TEMP[1]) - 1] = ZERO;
Code[1] = 0x3B;
ENDIF
ENDIF
re = 3;
ENDIF
WHILE strcmp(TEMP[0],RNum[Code[2]/0x10].R) NEQ ZERO AND Code[2] < 0xFF DO
Code[2] = Code[2] + 0x10;
ENDWHILE
WHILE strcmp(TEMP[1],RNum[Code[2]&0x0F].R) NEQ ZERO AND Code[2] < 0xFF DO
Code[2]++;
ENDWHILE
ENDIF
RETURN(re);
END
/************************ Inherent Code Analysis ****************************/
/************************* Branch Code Analysis *****************************/
/* */
/* ブランチ命令の処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Search_Branch(Instruction,Argment,Code,bc)
char *Instruction
,*Argment
,*Code;
int bc;
BEGIN
int Address,i,Count;
static struct
OP Bop[21] = {{"LBSR",0x17},{"LBRA",0x16}
,{"BSR",0x8D},{"BRA",0x20},{"BRN",0x21}
,{"BHI",0x22},{"BLS",0x23},{"BCC",0x24},{"BCS",0x25}
,{"BHS",0x24},{"BLO",0x25},{"BNE",0x26},{"BEQ",0x27}
,{"BVC",0x28},{"BVS",0x29},{"BPL",0x2A},{"BMI",0x2B}
,{"BGE",0x2C},{"BLT",0x2D},{"BGT",0x2E},{"BLE",0x2F}};
IF Argment[0] >= '0' AND Argment[0] <= '9' THEN
Address = atoi((char *)Argment);
ELSE
IF Argment[0] EQU '%' OR Argment[0] EQU '$' THEN
Address = BHconv(Argment[1]);
ELSE
IF Pass_flag NEQ ZERO THEN
i = 0;
WHILE strcmp(Argment,Symbol[i].SP) NEQ ZERO AND i < Symbol_Count DO
i++;
ENDWHILE
Address = (int)Symbol[i].SA;
ELSE
Address = 0x7FFF;
ENDIF
ENDIF
ENDIF
Count = i = 0;
IF strcmp(Instruction,Bop[i++].op) EQU ZERO THEN
Count = 3;
Code[0] = Bop[0].Code;
Code[1] = (Address - bc - Count) / 0x100 & 0xFF;
Code[2] = (Address - bc - Count) & 0xFF;
ELSEIF strcmp((char *)Instruction,Bop[i++].op) EQU ZERO THEN
Count = 3;
Code[0] = Bop[1].Code;
Code[1] = (Address - bc - Count) / 0x100 & 0xFF;
Code[2] = (Address - bc - Count) & 0xFF;
ELSE
WHILE NOT(strcmp( Instruction ,Bop[i].op) EQU ZERO
OR strcmp(&Instruction[1],Bop[i].op) EQU ZERO
AND Instruction[0] EQU 'L') AND i < 21 DO
i++;
ENDWHILE
IF i < 20 THEN
IF Instruction[0] EQU 'L' THEN
Count = 4;
Code[0] = 0x10;
Code[1] = Bop[i].Code;
Code[2] = (Address - bc - Count) / 0x100 & 0xFF;
Code[3] = (Address - bc - Count) & 0xFF;
ELSE
Count = 2;
Code[0] = Bop[i].Code;
Code[1] = (Address - bc - Count) & 0xFF;
ENDIF
ENDIF
ENDIF
ENDIF
RETURN(Count);
END
/************************* Branch Code Analysis *****************************/
/*********************** ExImmediate Code Analysis **************************/
/* イミディエートコードのない命令全般を処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION ExImmediate_Code(Instruction,Argment,ArgmentC,Code)
char *Instruction
,*Argment;
int ArgmentC;
char *Code;
BEGIN
static struct
OP EI1op[17] = {{ "NEG",0x00},{ "OIM",0x01},{ "AIM",0x02},{ "COM",0x03}
,{ "LSR",0x04},{ "EIM",0x05},{ "ROR",0x06},{ "ASR",0x07}
,{ "ASL",0x08},{ "ROL",0x09},{ "DEC",0x0A},{ "TIM",0x0B}
,{ "INC",0x0C},{ "TST",0x0D},{ "JMP",0x0E},{ "CLR",0x0F}
,{ "LSL",0x08}};
static struct
OP EI2op[31] = {{"SUBA",0x90},{"SUBB",0xD0},{"CMPA",0x91},{"CMPB",0xD1}
,{"SBCA",0x92},{"SBCB",0xD2},{"SUBD",0x93},{"ADDD",0xD3}
,{"ANDA",0x94},{"ANDB",0xD4},{"BITA",0x95},{"BITB",0xD5}
,{ "LDA",0x96},{ "LDB",0xD6},{ "STA",0x97},{ "STB",0xD7}
,{"EORA",0x98},{"EORB",0xD8},{"ADCA",0x99},{"ADCB",0xD9}
,{ "ORA",0x9A},{ "ORB",0xDA},{"ADDA",0x9B},{"ADDB",0xDB}
,{"CMPX",0x9C},{ "LDD",0xDC} ,{ "STD",0xDD}
,{ "LDX",0x9E},{ "LDU",0xDE},{ "STX",0x9F},{ "STU",0xDF}};
static struct
OP E10op[18] = {{"SUBW",0x90},{"CMPW",0x91},{"SBCD",0x92},{"CMPD",0x93}
,{"BITD",0x95},{ "LDW",0x96},{ "STW",0x97}
,{"EORD",0x98},{"ADCD",0x99},{ "ORD",0x9A},{"ADDW",0x9B}
,{"CMPY",0x9C} ,{ "LDY",0x9E},{ "STY",0x9F}
,{ "LDQ",0xDC},{ "STQ",0xDD},{ "LDS",0xDE},{ "STS",0xDF}};
static struct
OP E11op[15] = {{"SUBE",0x90},{"CMPE",0x91} ,{"CMPU",0x93}
,{ "LDE",0x96},{ "STE",0x97}
,{"ADDE",0x9B}
,{"CMPS",0x9C},{"DIVD",0x9D},{"DIVQ",0x9E},{"MULD",0x9F}
,{"SUBF",0xD0},{"CMPF",0xD1}
,{ "LDF",0xD6},{ "STF",0xD7}
,{"ADDF",0xDB}};
int re;
IF (re = NIC_Analysis(Instruction,Argment,ArgmentC
, Code ,Code_Info[0],EI1op,17)) EQU ZERO THEN
IF (re = NIC_Analysis(Instruction,Argment,ArgmentC
, Code ,Code_Info[1],EI2op,31)) EQU ZERO THEN
IF (re = NIC_Analysis(Instruction,Argment,ArgmentC
,&Code[1],Code_Info[1],E10op,18)) EQU ZERO THEN
IF (re = NIC_Analysis(Instruction,Argment,ArgmentC
,&Code[1],Code_Info[1],E11op,15)) EQU ZERO THEN
ELSE
re++;
Code[0] = 0x11;
ENDIF
ELSE
re++;
Code[0] = 0x10;
ENDIF
ENDIF
ENDIF
RETURN(re);
END
/*********************** ExImmediate Code Analysis **************************/
/*********************** InImmediate Code Analysis **************************/
/* */
/* イミディエートコードを含む命令全般を処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION NIC_Analysis(Instruction,Argment,ArgmentC,Code,Code_Info,CP,CPc)
char *Instruction
,*Argment;
int ArgmentC;
char *Code
,*Code_Info;
struct OP *CP;
int CPc;
BEGIN
int i,j,re,Offset;
i = j = re = 0;
WHILE strcmp(Instruction,CP[i].op) NEQ ZERO AND i < CPc DO
i++;
ENDWHILE
IF i < CPc THEN
Code[0] = CP[i].Code;
IF ArgmentC EQU 1 THEN
switch(Argment[0])
BEGIN
case'<':
IF Argment[1] EQU '%' OR Argment[1] EQU '$' THEN
Offset = BHconv(&Argment[1]);
ELSE
Offset = atoi(&Argment[1]);
ENDIF
Code[1] = Offset;
re = 2;
break;
case'#':
IF Argment[1] EQU '%' OR Argment[1] EQU '$' THEN
Offset = BHconv(&Argment[1]);
ELSE
Offset = atoi(&Argment[1]);
ENDIF
IF Instruction[0] NEQ 'S' OR Instruction[1] NEQ 'T' THEN
Code[0] = (Code[0] & 0xCF) | Code_Info[1];
IF Instruction[strlen(Instruction) - 1] EQU 'D' THEN
Code[1] = Offset / 0x100 & 0xFF;
Code[2] = Offset & 0xFF;
re = 3;
ELSE
Code[1] = Offset & 0xFF;
re = 2;
ENDIF
ENDIF
break;
case'>':
IF Argment[1] EQU '%' OR Argment[1] EQU '$' THEN
Offset = BHconv(&Argment[1]);
ELSE
Offset = atoi(&Argment[1]);
ENDIF
Code[0] = (Code[0] & 0xCF) | Code_Info[0];
Code[1] = Offset / 0x100 & 0xFF;
Code[2] = Offset & 0xFF;
re = 3;
break;
case'[':
Code[0] = (Code[0] & 0xCF) | Code_Info[2];
Code[1] = 0xAF;
Code[2] = Offset / 0x100 & 0xFF;
Code[3] = Offset & 0xFF;
re = 4;
break;
default:break;
END
ELSE
IF ArgmentC EQU 2 THEN
Code[0] = (Code[0] & 0xCF) | Code_Info[2];
IF (re = Direct_or_InDirect(Argment,&Code[1])) > ZERO THEN
j = 0;
re++;
ENDIF
ENDIF
ENDIF
ENDIF
RETURN(re)
END
/*********************** ExImmediate Code Analysis **************************/
/************************** Direct or InDirect *****************************/
/* */
/* ダイレクト及びインダイレクトの判定。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Direct_or_InDirect(Argment,Code)
char *Argment
,*Code;
BEGIN
char *TEMP[2],buffer[20];
int Return_Variable = 0;
TEMP[0] = buffer;
strcpy(TEMP[0],Argment);
TEMP[1] = TEMP[0] + strlen(TEMP[0]) + 1;
strcpy(TEMP[1],&Argment[strlen(Argment) + 1]);
IF TEMP[0][0] EQU '[' THEN
IF TEMP[1][strlen(TEMP[1]) - 1] EQU ']' THEN
strcpy(TEMP[0],&Argment[1]);
TEMP[1][strlen(TEMP[1]) - 1] = ZERO;
IF (Return_Variable = PostByte_Analysis(TEMP,Code)) > ZERO THEN
Code[0] = Code[0] | 0x10;
IF (Code[0] & 0x8F) EQU 0x8F THEN
Code[0] = Code[0] & 0xF0;
ENDIF
ENDIF
ENDIF
ELSE
Return_Variable = PostByte_Analysis(TEMP,Code);
ENDIF
RETURN(Return_Variable);
END
/************************** Direct or InDirect *****************************/
/*************************** PostByte Analysis ******************************/
/* */
/* ポストバイトの解析。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION PostByte_Analysis(Argment,Code)
char **Argment
,*Code;
BEGIN
int Byte_Length;
IF (Byte_Length = PCW_Judgment(Argment,Code)) EQU ZERO THEN
IF (Byte_Length = AutoInc_Judgment(Argment,Code)) EQU ZERO THEN
IF (Byte_Length = Acc_Judgment(Argment,Code)) EQU ZERO THEN
ENDIF
ENDIF
ENDIF
RETURN(Byte_Length);
END
/*************************** PostByte Analysis ******************************/
/************************** Bit Length Judgment *****************************/
/* */
/* 相対アドレスのビット長の計算。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION BitLen(Offset)
int Offset;
BEGIN
int Bit_Length = 0;
IF Offset NEQ ZERO THEN
IF Offset >= -16 AND Offset < 16 THEN
Bit_Length = 5;
ELSE
IF Offset >= -128 AND Offset < 128 THEN
Bit_Length = 8;
ELSE
IF Offset >= -32768 AND Offset < 32768 THEN
Bit_Length = 16;
ENDIF
ENDIF
ENDIF
ENDIF
RETURN(Bit_Length);
END
/************************** Bit Length Judgment *****************************/
/***************** PC Register And W Register Judgment **********************/
/* */
/* PCレジスタとWレジスタの判定。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION PCW_Judgment(Argment,Code)
char **Argment
,*Code;
BEGIN
int Bit_Length,Byte_Length,Offset,i;
IF Argment[0][0] EQU '%' OR Argment[0][0] EQU '$' THEN
Offset = BHconv(Argment[0]);
ELSE
Offset = atoi(Argment[0]);
ENDIF
IF Offset > ZERO OR strlen(Argment[0]) EQU ZERO THEN
Bit_Length = BitLen(Offset);
Byte_Length = 0;
IF strcmp(Argment[1],"PCR") EQU ZERO THEN
Code[0] = 0x8C;
IF Bit_Length > 8 THEN
Code[0] = Code[0] | 0x01;
Code[1] = Offset / 0x100 & 0xFF;
Code[2] = Offset & 0xFF;
Byte_Length = 3;
ELSE
Code[1] = Offset & 0xFF;
Byte_Length = 2;
ENDIF
ENDIF
IF strcmp(Argment[1], "W") EQU ZERO THEN
Code[0] = 0x8F;
Byte_Length = 1;
IF Bit_Length NEQ ZERO THEN
Code[0] = Code[0] | 0x20;
Code[1] = Offset / 0x100 & 0xFF;
Code[2] = Offset & 0xFF;
Byte_Length = 3;
ENDIF
ENDIF
i = 0;
WHILE strcmp(Argment[1],Post_Register[i]) NEQ ZERO AND i < 4 THEN
i++;
ENDWHILE
IF i < 4 THEN
Code[0] = (char)(i * 0x20);
Byte_Length = 1;
SWITCH(Bit_Length)
CASE( 0)
Code[0] = Code[0] | 0x84 ;BREAK
CASE( 5)
Code[0] = Code[0] | Offset ;BREAK
CASE( 8)
Code[0] = Code[0] | 0x88 ;
Code[1] = Offset & 0xFF;
Byte_Length++ ;BREAK
CASE(16)
Code[0] = Code[0] | 0x89 ;
Code[1] = Offset / 0x100 & 0xFF;
Code[2] = Offset & 0xFF;
Byte_Length = 3 ;BREAK
DEFAULT BREAK
ENDSWITCH
ENDIF
ELSE
Byte_Length = 0;
ENDIF
RETURN(Byte_Length);
END
/***************** PC Counter And W Register Judgment ***********************/
/*********************** Auto Incriment Judgment ****************************/
/* */
/* オートインクリメントの処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION AutoInc_Judgment(Argment,Code)
char **Argment
,*Code;
BEGIN
int i = 0,j = 0,Byte_Length = 0;
IF Argment[1][strlen(Argment[1]) - 1] EQU '+' THEN
Code[0] = 0x80;
Argment[1][strlen(Argment[1]) - 1] = ZERO;
IF Argment[1][strlen(Argment[1]) - 1] EQU '+' THEN
Code[0] = Code[0] | 0x01;
Argment[1][strlen(Argment[1]) - 1] = ZERO;
IF strcmp(Argment[1],"W") EQU ZERO THEN
Byte_Length = 1;
Code[0] = 0xCF;
ENDIF
ENDIF
WHILE strcmp(Argment[1],Post_Register[i]) NEQ ZERO AND i < 4 DO
i++;
ENDWHILE
IF i < 4 THEN
Byte_Length = 1;
Code[0] = Code[0] | (char)(i * 0x20);
ENDIF
ENDIF
IF Argment[1][0] EQU '-' THEN
Code[0] = 0x82;
j = 1;
IF Argment[1][1] EQU '-' THEN
Code[0] = Code[0] | 0x01;
j++;
IF strcmp(&Argment[1][2],"W") EQU ZERO THEN
Byte_Length = 1;
Code[0] = 0xEF;
ENDIF
ENDIF
WHILE strcmp(&Argment[1][j],Post_Register[i]) NEQ ZERO AND i < 4 DO
i++;
ENDWHILE
IF i < 4 THEN
Byte_Length = 1;
Code[0] = Code[0] | (char)(i * 0x20);
ENDIF
ENDIF
RETURN(Byte_Length);
END
/*********************** Auto Incriment Judgment ****************************/
/************************ Accumulators Jugment ******************************/
/* */
/* アキュムレータレジスタとインデックスレジスタの演算を含んだ処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Acc_Judgment(Argment,Code)
char **Argment
,*Code;
BEGIN
int i = 0;
WHILE strcmp(Argment[1],Post_Register[i]) NEQ ZERO AND i < 4 DO
i++;
ENDWHILE
IF i < 4 THEN
Code[0] = (char)(i * 0x20);
i = 1;
IF strcmp(Argment[0],"A") EQU ZERO THEN
Code[0] = Code[0] | 0x86;
ELSE
IF strcmp(Argment[0],"B") EQU ZERO THEN
Code[0] = Code[0] | 0x85;
ELSE
IF strcmp(Argment[0],"D") EQU ZERO THEN
Code[0] = Code[0] | 0x8B;
ELSE
IF strcmp(Argment[0],"E") EQU ZERO THEN
Code[0] = Code[0] | 0x87;
ELSE
IF strcmp(Argment[0],"F") EQU ZERO THEN
Code[0] = Code[0] | 0x8A;
ELSE
IF strcmp(Argment[0],"W") EQU ZERO THEN
Code[0] = Code[0] | 0x8E;
ELSE
i = 0;
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
RETURN(i)
END
/************************* Accumulators Judgment ****************************/
/************************** InInstruction ***********************************/
/* */
/* データ部表記用疑似命令処理。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION InInstruction(Instruction,Argment,ArgmentC,Code)
char *Instruction
,*Argment;
int ArgmentC;
char *Code;
BEGIN
int i = 0,Byte_Count = 0;
char *TP,Delimiter;
TP = Argment;
IF strcmp(Instruction,"FCB") EQU ZERO THEN
WHILE Byte_Count < ArgmentC DO
Code[Byte_Count++] = atoi(TP);
TP = TP + strlen(TP) + 1;
ENDWHILE
ELSE
IF strcmp(Instruction,"FDB") EQU ZERO THEN
WHILE (Byte_Count / 2) < ArgmentC DO
Code[Byte_Count++] = atoi(TP) / 0x100 & 0xFF;
Code[Byte_Count++] = atoi(TP) & 0xFF;
TP = TP + strlen(TP) + 1;
ENDWHILE
ELSE
IF strcmp(Instruction,"FCC") EQU ZERO
OR strcmp(Instruction,"FCS") EQU ZERO THEN
IF Argment[0] > 0x20 AND Argment[0] <= 0x2F THEN
Delimiter = Argment[0];
i = 1;
WHILE Argment[i] NEQ Delimiter DO
Code[Byte_Count++] = Argment[i++];
ENDWHILE
ENDIF
IF strcmp(Instruction,"FCS") EQU ZERO THEN
Code[Byte_Count - 1] = Code[Byte_Count - 1] | 0x80;
ENDIF
ENDIF
ENDIF
ENDIF
RETURN(Byte_Count);
END
/************************** InInstruction ***********************************/
/************************** Symbol Print ************************************/
/* */
/* シンボルネームの一覧。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Symbol_Print(Symbol,Symbol_Count,flag)
struct SYM *Symbol;
int Symbol_Count,flag;
BEGIN
int i,j;
i = j = 0;
printf("\n");
WHILE j < Symbol_Count DO
printf("%04d %s ",j,Symbol[j].SP);
IF flag EQU ZERO THEN
WHILE (i + strlen(Symbol[j].SP)) < 66 DO
printf("-");i++;
ENDWHILE
printf(" %04X\n",Symbol[j++].SA);
ELSE
WHILE (i + strlen(Symbol[j].SP) + strlen(Symbol[j - 1].SA)) < 70 DO
printf("-");i++;
ENDWHILE
printf(" %s\n",Symbol[j].SA);
ENDIF
i = 0;
ENDWHILE
RETURN(0);
END
/************************** Symbol Print ************************************/
/*************************** Dump Code **************************************/
/* アセンブルされたコードをダンプ形式で表示。 */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Dump_Code(Code,Count)
unsigned char *Code;
int Count;
BEGIN
int i,j;
i = j = 0;
printf("\n");
WHILE i < Count DO
printf("%04X ",i);
j = 0;
WHILE j++ < 16 DO
printf("%02X ",Code[i++]);
ENDWHILE
printf(" ");
j = 0;
i = i - 16;
WHILE j++ < 16 DO
IF Code[i] > 0x20 THEN
printf("%1c",Code[i]);
ELSE
printf(".");
ENDIF
i++;
ENDWHILE
printf("\n");
ENDWHILE
RETURN(0);
END
/*************************** Dump Code **************************************/
/*********************** Command Line Print *********************************/
/* */
/* コマンドラインの表示。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Command_Line_Print(ComLine,bc,c)
COMLINE ComLine;
int bc,c;
BEGIN
int j;
char *TP;
IF c NEQ ZERO THEN
printf("%04X ",bc);
ELSE
printf(" ");
ENDIF
j = 0;
WHILE j < 8 DO
IF j++ < c THEN
printf("%02X ",(unsigned char)PArea[bc++]);
ELSE
printf(" ");
ENDIF
ENDWHILE
WHILE j++ < c DO bc++; ENDWHILE
printf("%-10s",ComLine.Label);
printf("%-6s" ,ComLine.Instruction);
j = 0;
TP = ComLine.Argment;
printf("%s",TP);
WHILE j++ < ComLine.ArgmentC - 1 DO
TP = TP + strlen(TP) + 1;
printf(",%s",TP);
ENDWHILE
printf("\n");
RETURN(0);
END
/*********************** Command Line Print *********************************/
/************************ Symbol Entry **************************************/
/* */
/* シンボル,EQU,SET命令のラベルを登録。 */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION Symbol_Entry(ComLine,Symbol,Count)
COMLINE ComLine;
SYMBOL *Symbol;
int Count[];
BEGIN
int i = 0;
IF strlen(ComLine.Label) > 0 THEN
WHILE strcmp(ComLine.Label,Symbol[i].SP) NEQ ZERO AND i++ < Count[0] DO
ENDWHILE
IF i < Count[0] THEN
IF strcmp(ComLine.Instruction,"SET") NEQ ZERO THEN
printf("Error !!\n");
i = -1;
ELSE
ENDIF
ELSE
strcpy(Symbol[Count[0]++].SP,ComLine.Label);
Symbol[Count[0]].SP = Symbol[Count[0]-1].SP + strlen(ComLine.Label ) + 1;
IF strcmp(ComLine.Instruction,"SET") EQU ZERO
OR strcmp(ComLine.Instruction,"EQU") EQU ZERO THEN
strcpy(Symbol[Count[0] - 1].SA,ComLine.Argment);
Symbol[Count[0]].SA= Symbol[Count[0]-1].SA+strlen(ComLine.Argment) + 1;
ENDIF
ENDIF
ELSE
i = -1;
ENDIF
RETURN(i);
END
/************************ Symbol Entry **************************************/
/*************************** BHconv *****************************************/
/* アセンブルされたコードを */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/****************************************************************************/
FUNCTION BHconv(BH)
unsigned char BH[];
BEGIN
int I = 0,i = 1;
IF BH[0] EQU '%' THEN
WHILE BH[i] EQU 0x30 OR BH[i] EQU 0x31 DO
I = I * 2;
I = I + BH[i++] - '0';
ENDWHILE
ENDIF
IF BH[0] EQU '$' THEN
WHILE BH[i] >= '0' AND BH[i] <= '9'
OR BH[i] >= 'A' AND BH[i] <= 'F' DO
I = I * 0x10;
IF BH[i] > '9' THEN
I = I + BH[i] - 'A' + 10;
ELSE
I = I + BH[i] - '0';
ENDIF
i++;
ENDWHILE
ENDIF
RETURN(I);
END
/*************************** BHconv *****************************************/